home *** CD-ROM | disk | FTP | other *** search
/ Aminet 45 / Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso / Aminet / game / role / ldmud-3.2-bin.lha / mud / doc / concepts / negotiation < prev    next >
Text File  |  2001-04-06  |  12KB  |  259 lines

  1. CONCEPT
  2.         Telnet Negotiations
  3.  
  4. DESCRIPTION
  5.         Telnet negotiations are being used for transmitting status
  6.         and general informations between telnet-client und server.
  7.         They are specified in their respective RFCs (Request For
  8.         Comments) which define the standard-way-to-do-it.
  9.  
  10.         Check following for the options mentioned herein:
  11.         RFC 0854 for the telnet protocol specification
  12.         RFC 0857 for ECHO         /* no, not mentioned here, but used */
  13.         RFC 1073 for NAWS         /* in Amylaar's windowsize          */
  14.         RFC 1091 for TERMINAL TYPE
  15.         RFC 1096 for XDISPLAY LOCATION
  16.         RFC 1408 for ENVIRON
  17.         RFC 1184 for LINEMODE
  18.         RFC 0855 for End Of Record
  19.  
  20.         All negotiations start with the special character IAC which is
  21.         defined in /usr/include/arpa/telnet.h (or in
  22.         src/driver/telnet.h for 3.2(.1)) and has the decimal value of
  23.         255. Negotiations are based on different telnetoptions (their
  24.         values are defined in telnet.h too). Before a negotiation can
  25.         start the client and the server have to agree that they
  26.         support the option.
  27.         This works in the following way:
  28.  
  29.         If a client wants to send something to the server it has to
  30.         send 'IAC WILL option' (For terminaltype negotation this would
  31.         be the 3 bytes 255,251,24; again, check telnet.h) to confirm
  32.         that it is able to do that. If the server is supporting that
  33.         option and wants to receive something it sends 'IAC DO option'
  34.         (255,253,option)
  35.  
  36.         If one side is receiving an 'IAC WILL option' and has not yet
  37.         sent with DO or DONT it has to respond with either 'IAC DO
  38.         option' if it will support this negotiation or 'IAC DONT
  39.         option' if it won't.
  40.  
  41.         If one side is receiving an 'IAC DO option' and has not yet
  42.         sent a WILL or WONT it has to reply with either 'IAC WILL
  43.         option' if it supports the option or 'IAC WONT option' if not.
  44.  
  45.         A small example: Lets assume we want to negotiating
  46.         terminaltype. (TELOPT_TTYPE with value 24). client is the
  47.         telnet executable on the playerside, the server is the
  48.         gamedriver.
  49.  
  50.                 client                        server
  51.             IAC WILL TTYPE                
  52.                                     IAC DO TTYPE
  53.  
  54.         Or:
  55.                                     IAC DO TTYPE
  56.             IAC WILL TTYPE
  57.  
  58.         After this we are ready to transfer the terminaltype from the
  59.         client to the server as explained below.
  60.  
  61.         Now we are ready to start the real negotiations. I explain the
  62.         3 options I have currently implemented.
  63.  
  64.         First TerminalType aka TTYPE aka 24 aka TELOPT_TTYPE assuming
  65.         the client and the server have exchanged WILL/DO.
  66.  
  67.         The server is now free to send 'IAC SB TELOPT_TTYPE
  68.         TELQUAL_SEND IAC SE' which will be replied with 'IAC SB
  69.         TELOPT_TTYPE TELQUAL_IS terminaltype IAC SE' where
  70.         terminaltype is a non-zero terminated string (it's terminated
  71.         by the IAC) (For values look up telnet.h) AND switch the
  72.         client's terminalemulation to 'terminaltype'. terminaltype is
  73.         case-insensitive. terminal-type may be UNKNOWN. The server may
  74.         repeat the SEND request and the client will respond with the
  75.         next preferred terminaltype. If this is the same as the
  76.         previous received, it marks the end of the list of
  77.         terminaltypes. The next SEND request will start the
  78.         terminaltypes from the beginning.
  79.  
  80.         Example: (we have exchanged WILL/DO already)
  81.                   client                                server
  82.                                         IAC SB TTYPE SEND IAC SE
  83.         IAC SB TTYPE IS VT200 IAC SE
  84.                                         IAC SB TTYPE SEND IAC SE
  85.         IAC SB TTYPE IS VT100 IAC SE
  86.                                         IAC SB TTYPE SEND IAC SE
  87.         IAC SB TTYPE IS VT52 IAC SE
  88.                                         IAC SB TTYPE SEND IAC SE
  89.         IAC SB TTYPE IS VT52 IAC SE
  90.         /* this marks that we have all terminaltypes. We decide to use the
  91.          * vt200 mode so we have to skip to VT200
  92.          */
  93.                                         IAC SB TTYPE SEND IAC SE
  94.         IAC SB TTYPE IS VT200 IAC SE
  95.  
  96.  
  97.         Next important option is NAWS (31) or WindowSizeNegotiation.
  98.  
  99.         This one is a bit easier than terminaltype. After having
  100.         received a IAC DO NAWS from the server, the client will reply
  101.         with IAC WILL NAWS and immediately after that send IAC SB NAWS
  102.         columns_high columns_low lines_high lines_low IAC SE where
  103.         xx_low refers to the lowbyte of xx and xx_high refers to the
  104.         highbyte of xx. This will be automagically resent at every
  105.         windowresize (when the client gets a SIGWINCH for example) or
  106.         at your request with 'IAC SB NAWS SEND IAC SE'.
  107.  
  108.         Example: (WILL/DO exchanged)
  109.                 client                                server
  110.         IAC SB NAWS 0 80 0 24 IAC SE         /* the standard vt100 windowsize */
  111.                                         /* no reply */
  112.  
  113.         And, a bit less important but most complex, the LINEMODE (34)
  114.         option. It was implemented it due to the fact, that
  115.         some weird DOS telnets would not work otherwise. Implemented
  116.         are only the absolute basic feature, which is the actual
  117.         switching the telnet to linemode. After exchanging WILL/DO the
  118.         server sends a modechange request to the client using IAC SB
  119.         LINEMODE LM_MODE MODE_EDIT IAC SE, which should turn on local
  120.         commandline-editing for the client. If a client supports
  121.         LINEMODE it HAS to support this modechange. The client will
  122.         reply with IAC SB LINEMODE LM_MODE MODE_EDIT|MODE_ACK IAC SE
  123.         (x|y is bitwise or). Thats it for linemode. (You will perhaps
  124.         receive other IAC SB LINEMODEs with other LM_xxx ... you may
  125.         ignore them. (At least IRIX 5.x sends IAC SB LINEMODE LM_SLC
  126.         .... IAC SE which declares the local characterset.)).
  127.  
  128.         Example: (WILL/DO negotiated)
  129.  
  130.                 client                                        server
  131.                                                 IAC SB LINEMODE LM_MODE
  132.                                                        MODE_EDIT IAC SE
  133.         IAC SB LINEMODE LM_MODE
  134.           MODE_EDIT|MODE_ACK IAC SE
  135.  
  136.         Note: The option is much more funnier as it looks here, it for
  137.           example supports a mixed mode between linemode and
  138.           charactermode... flushing the input at certain characters (at
  139.           ESC or TAB for shell-like commandline completition). We suggest
  140.           reading RFC 1184.
  141.  
  142.         You might be interested in TELOPT_XDISPLAYLOC and TELOPT_ENVIRON too.
  143.  
  144.         Now, how to implement this using LDMud?
  145.  
  146.         0. Patch src/driver/comm1.c, function init_telopts() to include
  147.             telopts_do[TELOPT_XXX] = reply_h_telnet_neg;
  148.             telopts_dont[TELOPT_XXX] = reply_h_telnet_neg;
  149.             telopts_will[TELOPT_XXX] = reply_h_telnet_neg;
  150.             telopts_wont[TELOPT_XXX] = reply_h_telnet_neg;
  151.            for every telnet negotiation you want to use.
  152.            Do not overwrite the TELOPT_ECHO and TELOPT_SGA hooks.
  153.  
  154.            Alternatively, set the driver hook H_NOECHO in master.c:
  155.            this diverts _all_ telnet data into the mudlib.
  156.  
  157.         1. Add a new driver hook to master.c just below the others.
  158.                 set_driver_hook(H_TELNET_NEG,"telnet_neg"),
  159.         2. Make a telnet.h for your mudlib... just change the arrays in
  160.                 src/driver/telnet.h.
  161.         3. define a function
  162.  
  163.                 void telnet_neg(int cmd, int option, int * optargs)
  164.  
  165.            in your interactive objects (login.c , shells, player.c or
  166.            whereever). And note, in ALL objects, through which a
  167.            player is handed through (in TAPPMud these are login.c and
  168.            player.c). [Ok, master.c is interactive for a very short
  169.            time too, but it won't accept input, will it?]
  170.            'cmd' will be TELCMD_xxxx (see telnet.h), 'option' one of
  171.            TELOPT_xxxx and 'optargs' will be an array of ints (bytes in
  172.            fact) when 'cmd' is SB.
  173.            Parse 'cmd'/'option' and reply with appropiate answers
  174.            using binary_message() (appropiate meaning sending the
  175.            right DO/DONT/WILL/WONT if not sent before and using the SB
  176.            return values).
  177.         3.1. Sent IAC DO TTYPE IAC DO NAWS IAC DO LINEMODE at the
  178.            first time you can do it (before cat()ing /WELCOME perhaps).
  179.         3.2. Note all sent and received WILL/WONT/DO/DONT options for
  180.            conforming to the standard, avoiding endless loops and for
  181.            easy debugging :)
  182.         3.3. Pass those recevied/sent data and other data when the
  183.            interactive object is changed (from login.c to player.c or
  184.            at other bodychanges). Clear the data when the player goes
  185.            linkdead or quits. You won't need to save this data.
  186.         3.4. Lower_case() terminaltypes... ;)
  187.         3.5. Use reasonable defaultvalues if the client does not
  188.            support one of the options. (columns 80,lines 24 if not
  189.            NAWS, unknown or vt100 for no terminaltype)
  190.  
  191.         The WILL/WONT/DO/DONT data is best saved in a mapping looking
  192.         like this:
  193.           ([ "received": ([ option1: DO_DONT_OR_0;WILL_WONT_OR_0, ... ])
  194.            , "sent"    : ([ option1: DO_DONT_OR_0;WILL_WONT_OR_0, ... ])
  195.           ])
  196.  
  197.         (Ok, it can be done better. But not without confusing *me*
  198.         more.)
  199.  
  200.         Before sending anything check
  201.           TN["sent"][option,0_if_do_dont_or_1_if_will_wont]
  202.         so you don't enter endless loops, save network traffic and the
  203.         like.
  204.  
  205.         The windowsize is best saved in the players environment
  206.         variables so that he can modify them later on. (Or in two
  207.         integers in the player object...). Use for these values is
  208.         clear I think.
  209.  
  210.         The terminaltypes received using above mentioned method are
  211.         best stored in an array. The actual set terminaltype is best
  212.         stored in an environment variable where the player can modify
  213.         it. Upon modifying it the IAC SB TTYPE SEND IAC SE cycle
  214.         should be started to match the emulation to the entered new
  215.         terminaltype. You then may use data retrieved from
  216.         /etc/termcap (man 5 termcap) or /usr/lib/terminfo/*/* (SysVID,
  217.         man 5 terminfo) to implement terminalcontrol codes dependend
  218.         on the terminaltype. /etc/termcap may prove to be the easiest
  219.         way tough /usr/lib/terminfo/*/* is the newer (and better) SysV
  220.         way of doing it.
  221.  
  222.         [Anyone got a description of the internal terminfo format for
  223.         me? -Marcus]
  224.  
  225.         LINEMODE replies may be left alone if only using the mode
  226.         change to MODE_EDIT
  227.  
  228.         Some statistics about what clients support telnet negotiations:
  229.  
  230.         Tinyfugue and some other mudclients usually do not support
  231.         negotiations.
  232.         Except for TF, which supports the Telnet End-Of-Record option
  233.         as marker for the end of the prompt. So if you send IAC EOR
  234.         after every prompt, it will print the prompt always in the
  235.         input window. (Do not forget to negotiate that. First IAC WILL
  236.         TELOPT_EOR/wait for IAC DO TELOPT_EOR). Newer versions of
  237.         TF will support NAWS and there will be a patch for TTYPE
  238.         negotiation available soon.
  239.  
  240.         All telnets able to do negotiations I've encountered support
  241.         the TTYPE option.
  242.         HP9.x,Irix5.x,Linux,EP/IX,CUTELNET/NCSATELNET (Novell) and
  243.         perhaps more support NAWS.
  244.         At least Irix5.x,Linux,CU/NCSATELNET support LINEMODE.
  245.         SUN does not support NAWS and LINEMODE neither in SunOS 4.1.3
  246.         nor in Solaris 2.3.
  247.  
  248.         For getting RFCs you can for example use
  249.         ftp://ftp.uni-erlangen.de/pub/doc/rfc/
  250.  
  251.  
  252. BUGS
  253.         Not all aspects of the options are mentioned to keep this doc
  254.         at a reasonable size. Refer to the RFCs to get more confused.
  255.  
  256. CREDITS
  257.         Provided by Marcus@TAPPMud (Marcus Meissner,
  258.         <msmeissn@cip.informatik.uni-erlangen.de>).
  259.